﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Data;
using System.Web.UI.WebControls;
using vudu.EnlaceDatos.SqlServer;
using vudu.Logica.Clases;
using vudu.PaginasWeb.G6Pensum;

namespace vudu.PaginasWeb.G6Pensum
{
    public partial class CrearPensumElegir : System.Web.UI.Page
    {
        private List<Materia> _ListaMateriaElegir;
        private List<Materia> ListaDelGridView2 = new List<Materia>();
        private List<Materia> ListaPrelacion = new List<Materia>();
        private List<Prelacion> _ListaPrelacion; //new List<Prelacion>();
        private List<Object> categoryIDList = new List<Object>();
        private Prelacion prelacion = new Prelacion();
        private Pensum pensum = new Pensum();
        private Materia ElegidaMateria = new Materia();
        private int ColumnaSemestre = 1;
        // Estatus del pensum, como se crea un nuevo pensum, se insertar como DESACTIVADO
        private String Status = "DESACTIVADO";
        // ID de la Escuela
        private int IdEscuela = 1;
        
       

        #region Constructor
        public CrearPensumElegir()
        {
            ListaMateriaElegir = new List<Materia>();
        }
       
        #endregion

        #region getter y setter
        public List<Materia> ListaMateriaElegir
        {
            get
            {
                return _ListaMateriaElegir;
            }
            set
            {
                _ListaMateriaElegir = value;
            }
        }
        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
         
          // Variables de Session para validar que es el usuario de Escuela
            string miRol = (string)Session["rol"];
            if (miRol != "Escuela")
                Response.Redirect("../G3AccesoSistema/InicioSistema.aspx");
            // le asignamos lo que trae la variable session del usuario 
            Escuela escuela = (Escuela)Session["Usuario"];
            // le pasamos al label el nombre de la escuela pasada por session
            nombreEscuela.Text = "Escuela: " + escuela.NombreEscuela;
            IdEscuela = escuela.IdEscuela;
            
            if (!IsPostBack)
            {
                // Inicializamos todos los objetos cuando entra la primera vez al postback de la pagina
                   prelacion = new Prelacion();
                   pensum = new Pensum();
                   ElegidaMateria = new Materia();
                  _ListaMateriaElegir = new List<Materia>();
                  ListaDelGridView2 = new List<Materia>();
                  ListaPrelacion = new List<Materia>();
                  categoryIDList = new List<Object>();
                  
                // le asignamos a ListaMateriaEligir la lista de la pagina anterior
                ListaMateriaElegir = (List<Materia>)Session["MateriaAgregada"];
                // al primer gridview cargamos las materias provenientes de la pagina anteriors
                GridView1.DataSource = cargarMateriaTabla1();
                GridView1.DataBind();
                // inicializamos el gridview2 con el DataTable vacio
                GridView2.DataSource = cargarGridView2Inicial();
                GridView2.DataBind();
                // le Asignamos a las variables session para guardar los gridview 1 y los gridview 2
                Session["Materias"] = GridView1.DataSource;
                Session["Prelaciones"] = cargarGridView2Inicial();
                Session["MateriaAgregada"] = null;
                
                Session["Columnasemestre"]= ColumnaSemestre;
                // Ocultamos el ID del gridview1, dicha columna esta en la columna 4
                OcultarColumnas(GridView1,4);
                // Ocultamos el Id del gridview2, dicha Columna esta en la columna 1
                OcultarColumnas(GridView2,2);
                // Desabilitamos el Gridview2 para que no lo pueda modificar
                GridView2.Enabled = false;
            

            }
            else
            {

                // Guardamos la lista en una variable session para que en cada postback no se pierda la lista
                // de prelaciones
               _ListaPrelacion = (List<Prelacion>)Session["ListaClasePrelacion"];           
                
               // Ocultamos el Id del gridview2, dicha Columna esta en la columna 1
               OcultarColumnas(GridView2,2);
                // Desabilitamos el gridview2 completo para que el usurio no pueda hacer "Check"
                // en dicho Gridview
               GridView2.Enabled = false;
              
            }
            Session["MateriaAgregada"] = null;
        }

        // Ocultar Columna del ID de la materia en los dos Gridview!!
        public void OcultarColumnas(GridView grdView, int columna)
        {
            
            // colocamos la cabecera del gridview invisible colocando "false"
            grdView.HeaderRow.Cells[columna].Visible = false;
            // recorremos todo el grid pasado por parametro(sea el gridview1 o gridview2)
            foreach (GridViewRow row in grdView.Rows)
            {
                // nos paramos en la celda donde esta la columna del ID y ocultamos cada valor
                row.Cells[columna].Visible = false;
                // Si la variable Columna es igual a 4, es que estamos recorriendo el gridView1
               
            }
           
        }

        // Este metodo desabilita el combobox del gridview1, asi el usuario despues que 
        // inserte una nueva prelacion, no pueda modificar el semestre de la materia elegida
        public void DesabilitarControlGridView(GridView grdView, int columna)
        {
            // recorremos todo el grid pasado por parametro(sea el gridview1)
            foreach (GridViewRow row in grdView.Rows)
            {
                // recorremos cada fila y al columna del semestre la desabilitamos
                row.Cells[columna].Enabled = false;            
            }    
        }

        public void DesabilitarFila(GridView grdView)
        {
            // recorremos todo el grid pasado por parametro(sea el gridview1)
            foreach (GridViewRow row in grdView.Rows)
            {
                // recorremos cada fila y desabilitamos la fila que estuvo chequeada 
                CheckBox _check = row.FindControl("chkSeleccion") as CheckBox;
                if (_check.Checked)
                {
                    // inhabilitamos toda la fila, excepto el boton eliminar
                    row.Cells[0].Enabled = false;
                    row.Cells[1].Enabled = false;
                    row.Cells[2].Enabled = false;
                    row.Cells[3].Enabled = false;
                    // deschequeamos el Checkbox que habia sido seleccionado
                    _check.Checked = false;
                }
            }
        }
        // Este Metodo devuelve un Datatable con las materia a seleccionar
        // en el gridview 2
        public DataTable cargarMateriaTabla1()
        {
            // Generar la DataTable de la lista de materias
            DataTable table = new DataTable();
            table.Columns.Add("Materias Seleccionadas", typeof(string));
            table.Columns.Add("ID", typeof(string));
            // le asignamos al Datatable la lista
            foreach (Materia materia in _ListaMateriaElegir)
            {
                table.Rows.Add(materia.Nombre,materia.Codigo.ToString());
            }
            
            return table;
        }
        // Este metodo devuelve un DataTable el cual devuelve las posibles materias 
        // que se pueden seleccionar para una materia
        public DataTable cargarMateriaTabla2(List<Materia> _ListaMateriaEnviar)
        {
            // Generar la DataTable de la lista de materias
            DataTable table = new DataTable();
            table.Columns.Add("Materias Seleccionadas", typeof(string));
            table.Columns.Add("ID", typeof(string));
            // recorremos la Lista de Materias a enviar
            foreach (Materia materia in _ListaMateriaEnviar)
            {
                table.Rows.Add(materia.Nombre, materia.Codigo.ToString());
            }

            return table;
        }

       // Este metodo devuelve un DataTable inicializado con vacio para que cada vez
       // que se inserta una prelacion se coloque el gridview 2 inicializado
        public DataTable cargarGridView2Inicial()
        {
            int inicial = 0;
            // Generar la DataTable de la lista de materias
            DataTable table = new DataTable();
            table.Columns.Add("Materias Seleccionadas", typeof(string));
            table.Columns.Add("ID", typeof(string));
            // rellenamos en vacio el gridview 2
            while (inicial!=4)
            {
                table.Rows.Add(" - "," - ");
                inicial++;
            }
            // retornamos el DataTable
            return table; 
        }
        
        // Recorre el gridView 2 para ver que materias van hacer la prelacion de una determinada materia
        // y devuelve una lista del tipo "Materia", dicha lista es la lista de Prelaciones de una determinada materia
        public List<Materia> RecorrerGridView2()
        {
            // Instancio una lista del tipo Materia
            List<Materia> _PrelacionMateriaLista = new List<Materia>();
            // Se recorre todo el GridView 2 
            foreach (GridViewRow row in GridView2.Rows)
            {
                CheckBox _check = row.FindControl("chkSeleccionEscoger") as CheckBox;
                // si alguno de los botones esta chequeado se procede a llenar la lista de materias
                // las cuales prelan a una determinada Materia
                if (_check.Checked)
                {
                    Materia misMateriaPrelar = new Materia();
                    misMateriaPrelar.Nombre = row.Cells[1].Text;
                    misMateriaPrelar.Codigo = Convert.ToInt32(row.Cells[2].Text);
                    // Insertamos en la lista del tipo Materia
                    _PrelacionMateriaLista.Add(misMateriaPrelar);
        
                }
            }
            // retorno la lista de materias, las cuales son las prelaciones de una determinanda materia
            return _PrelacionMateriaLista;
        }

        // recorre el primer gridview para determinar que Checkbox ha sido chequeado
        // y luego se devuelve el valor de combobox semestre que ha sido chequeado
        public int RecorrerGridView1()
        {
            int ValorComboBox = 0;
            // Recorremos el gridview 1
            foreach (GridViewRow row in GridView1.Rows)
            {
                CheckBox _check = row.FindControl("chkSeleccion") as CheckBox;
                DropDownList _comboEscogido = row.FindControl("comboSemestre") as DropDownList;
                // valiamos si el Checbox ha sido chequeado
                if (_check.Checked)
                {
                    // Agarramos el valor del combobox seleccionado
                    ValorComboBox = Convert.ToInt32(_comboEscogido.SelectedValue);                        
                }
            }
            return ValorComboBox;
        }

        // Este metodo recorre todo el primer GridView para ver que Checkbox no ha sido chequeado
        // y asi poder insertar en el segundo GridView se valida las materias que estan por debajo
        //del semestre que se elegio
        public void GridView1_SelectedIndex(object sender, EventArgs e)
        {
            CheckBox Chequear = (CheckBox)sender;
            int _ValordelSemestre = 0;
            int _ValordelSemestre1 = 0;

            // Verificar si el Checkbox fue chequeado
            if (Chequear.Checked)
            {
                ListaPrelacion = new List<Materia>();
                // se llama al metodo RecorrerGridView1() el cual devuelve un int
                // con el valor del ComboBox chequeado.
                _ValordelSemestre1 = RecorrerGridView1();

                DataTable dtMaterias = Session["Materias"] as DataTable;
                DataTable dtPrelaciones = Session["Prelaciones"] as DataTable;
                // recorremos el gridView1
                foreach (GridViewRow row in GridView1.Rows)
                {
                    Materia materia = new Materia();
                    CheckBox _check = row.FindControl("chkSeleccion") as CheckBox;
                    DropDownList _comboEscogido = row.FindControl("comboSemestre") as DropDownList;
                    // verificamos cual fue el checkbox chequeado
                    if (!_check.Checked)
                    {
                        materia = new Materia();
                        _ValordelSemestre = Convert.ToInt32(_comboEscogido.SelectedValue);
                        // Validamos que el semestre que devuelve le metodo "RecorrerGridView1()"
                        // sea menor al semestre de la fila a la cual fue chequeada
                        if (_ValordelSemestre < _ValordelSemestre1)
                        {
                            materia.Nombre = row.Cells[3].Text;
                            materia.Codigo = Convert.ToInt32(row.Cells[4].Text);
                            // insertamos en la mista de materia, un objeto del tipo Materia a la lista
                            // que contendra las posibles prelaciones 
                            ListaDelGridView2.Add(materia);
                        }
                    }

                }
                // si la lista del gridview2 tiene aunque sea una fila carga las materias otra vez en el gridview2
                if (ListaDelGridView2.Count != 0)
                {
                    // cargamos el gridview 2 con el Datatable que devuelve el metodo CargarmateriaTabla2
                    GridView2.DataSource = cargarMateriaTabla2(ListaDelGridView2);
                    GridView2.Enabled = true;
                    GridView2.DataBind();
                    mensaje.Text = " ";
                }
                else
                {
                    // cargamos en el DataSource del gridview 2 lo que devuelve el metodo CargarGridview2Inicial
                    GridView2.DataSource = cargarGridView2Inicial();
                    GridView2.Enabled = true;
                    GridView2.DataBind();
                    mensaje.Text = "Esta Materia no tiene semestre por debajo de ella, O no ha elegido los semestres correctamente";
                }

                Session["Prelaciones"] = cargarMateriaTabla2(ListaDelGridView2);
                Session["Materias"] = GridView1.DataSource;

                botonSeleccionPrelacion.Enabled = true;
                OcultarColumnas(GridView2, 2);
            }
        }
        // Este el evento del metodo Agregar Prelacion se activa para asignarle
        // a una determinada materia sus prelaciones
        public void BotonAgregarPrelacion(Object sender, EventArgs e)
        {
            int numeroColumna = 2;
            bool verificarExistencia = false;
            DataTable dtMaterias = Session["Materias"] as DataTable;
            DataTable dtPrelaciones = Session["Prelaciones"] as DataTable;
            // devolvemos true o false si el usuario chequeo alguna materia
            verificarExistencia = InsertarPrelacionElegida();

            GridView2.DataSource = cargarGridView2Inicial();
            GridView2.DataBind();

            Session["Materias"] = GridView1.DataSource;
            Session["Prelaciones"] = cargarGridView2Inicial();
            // verificamos si efectivamente no ha seleccionado alguna materia
            if (!verificarExistencia)
            {
                // Desabilitamos la fila completa
                DesabilitarFila(GridView1);
                // Desabilitamos la columna de los semestres
                DesabilitarControlGridView(GridView1, 1);
            }

            Session["Columnasemestre"] = numeroColumna;
            OcultarColumnas(GridView2, 2);
            
           
            
        }

        // Este Metodo inserta en la lista del tipo "Prelacion"
        public bool InsertarPrelacionElegida()
        {
            prelacion = new Prelacion();
            bool verificar = false;
            // recorremos el gridview 1
            foreach (GridViewRow row in GridView1.Rows)
            {
                Materia materia = new Materia();
                Button boton = row.FindControl("botonEliminar") as Button;
                CheckBox _check = row.FindControl("chkSeleccion") as CheckBox;
                DropDownList _comboEscogido = row.FindControl("comboSemestre") as DropDownList;
                TextBox _TexboxCredito = row.FindControl("texboxCredito") as TextBox;
                // validamos que el checkbox haya sido chequeado en el gridview 2
                if (_check.Checked)
                {
                     // Instanciamos un objeto del tipo materia
                        ElegidaMateria.Nombre = row.Cells[3].Text;
                        ElegidaMateria.Codigo = Convert.ToInt32(row.Cells[4].Text);
                        prelacion.MiMateriaPensum = ElegidaMateria;
                        if (_comboEscogido.SelectedValue != null)
                            prelacion.SemestreMateriaPensum = Convert.ToInt32(_comboEscogido.SelectedValue);
                        
                        prelacion.CreditoMateriaPensum = Convert.ToInt32(_TexboxCredito.Text);
                        prelacion.Prelaciones = RecorrerGridView2();
                       // Verifico si la lista que devuelve esta vacia
                       // eso quierede decir que el usuario no selecciono alguna materia del gridview 2
                        if (prelacion.Prelaciones.Count != 0)
                        {         
                                if (_ListaPrelacion != null)
                                    this._ListaPrelacion.Add(prelacion);
                                else
                                {
                                    this._ListaPrelacion = new List<Prelacion>();
                                    this._ListaPrelacion.Add(prelacion);
                                }
                            
                        }
                        else
                        {
                            // Si la lista de Prelacioens esta vacia, muestra un mensaje de error
                            if (prelacion.Prelaciones.Count == 0)
                            {
                                mensaje.Text = " * Tiene que seleccionar al menos una materia";
                                verificar = true;
                            }
                        }
                                   
                }
                
            }
            
            Session["ListaClasePrelacion"] = _ListaPrelacion;
            return verificar;   
        }

        // metodo para insertar los valores de las listas en las clase pensum para luego pasarselo
        // a la clase SqlserverPensum
        public void InsertarPensum(List<Prelacion> _listaPrela, int creditos)
        {
            SqlServerPensum serverPensum = new SqlServerPensum();
            bool verificarInsertar = true;
            pensum.FechaInicio= DateTime.Now;
            pensum.FechaFin = DateTime.Now;
            pensum.CreditoPensum = creditos;
            pensum.ListaPrelaciones = _listaPrela;
            pensum.StatusPensum = Status;
            
            // se paso el objeto del tipo Pensum al metodo de la clase SqlserverPensum
            // el cual inserta la el pensum completo con todas sus prelaciones
           verificarInsertar = serverPensum.insertarPensum(pensum,IdEscuela);
           if (verificarInsertar)
           {
               ShowAlertMessage("El pensum fue creado con éxito");
           }
        }

        // Metodo que se ejecuta al momento de presionar el boton de "Crear Pensum"
        public void Crear_Onclick(Object sender, EventArgs e)
        {
            int IDMateriaActual = 0;
            int TotalCreditos = 0;
            bool VerificarExitirMateria = false;
            _ListaPrelacion = (List<Prelacion>)Session["ListaClasePrelacion"];

            if (_ListaPrelacion == null)
                this._ListaPrelacion = new List<Prelacion>();
            
            // recorremos todo el gridview
            foreach (GridViewRow row in GridView1.Rows)
            {
                CheckBox _check = row.FindControl("chkSeleccion") as CheckBox;
                DropDownList _comboEscogido = row.FindControl("comboSemestre") as DropDownList;
                TextBox _TexboxCredito = row.FindControl("texboxCredito") as TextBox;
               
                if (!_check.Checked)
                {
                    IDMateriaActual = Convert.ToInt32(row.Cells[4].Text);
                    // Recorremos la lista de las materias del pensum
                    if (_ListaPrelacion != null)
                    {
                        foreach (Prelacion prela in _ListaPrelacion)
                        {
                            if (IDMateriaActual == prela.MiMateriaPensum.Codigo)
                            {
                                VerificarExitirMateria = true;
                            }
                        }
                    }
                    // si la variable VerificarExitirMateria es "false" entonces
                    // a esa materia de esa fila, no se le han asignado prelaciones
                    if (VerificarExitirMateria == false)
                    {
                        // instancion un objeto del tipo materi y del tipo prelacion
                        try
                        {
                            prelacion = new Prelacion();
                            ElegidaMateria = new Materia();
                            ElegidaMateria.Nombre = row.Cells[3].Text;
                            ElegidaMateria.Codigo = Convert.ToInt32(row.Cells[4].Text);
                            prelacion.MiMateriaPensum = ElegidaMateria;
                            prelacion.SemestreMateriaPensum = Convert.ToInt32(_comboEscogido.SelectedValue);
                            prelacion.CreditoMateriaPensum = Convert.ToInt32(_TexboxCredito.Text);
                            prelacion.Prelaciones = null;

                            _ListaPrelacion.Add(prelacion);
                        }
                        catch
                        {
                            mensaje.Text= " * Una o varias Materia no tiene sus unidades de credito";
                        }
                    }
                }
                VerificarExitirMateria = false;
                TotalCreditos = TotalCreditos + (Convert.ToInt32(_TexboxCredito.Text));

            }
            // llamamos el metodo insertarPensum y le pasamos la lista de prelaciones
            // con el total de creditos
           InsertarPensum(_ListaPrelacion,TotalCreditos);
           _ListaPrelacion = null;
           Session["ListaClasePrelacion"] = null;
            // redireccionamos a la siquiente pagina para mostrar el pensum insertado
           //Response.Redirect("../G6Pensum/ListarPensum.aspx");
        }

        // Este metodo reinicia o borra todas las inserciones que se hayan hecho 
        public void ReiniciarPensum(Object sender, EventArgs e)
        {
            // le paso la lista guardada en el session
            _ListaPrelacion = (List<Prelacion>)Session["ListaClasePrelacion"]; 
           // recorremos el gridview 1
            foreach (GridViewRow row in GridView1.Rows)
            {
                CheckBox _check = row.FindControl("chkSeleccion") as CheckBox;
                DropDownList _comboEscogido = row.FindControl("comboSemestre") as DropDownList;
                TextBox _TexboxCredito = row.FindControl("texboxCredito") as TextBox;
                // si esta chequeado un Checkbo, se deschequea
                if (_check.Checked)
                {
                    _check.Checked = false;
                }
                //  seteamos el textbox de los creditos con "1"
                _TexboxCredito.Text = "1";
                // limpiamos cada combobox
                _comboEscogido.ClearSelection();
                // colocamos disponibles todas las columnas del gridview
                row.Cells[0].Enabled = true;
                row.Cells[1].Enabled = true;
                row.Cells[2].Enabled = true;
                row.Cells[3].Enabled = true;
        
                
            }
            // le asignamos a la lista de materias de pensum NUll para hacer el borrado completo
            _ListaPrelacion = null;
            // Ademas se lo asignamos a la variable de session
            Session["ListaClasePrelacion"] = _ListaPrelacion;
        }

        //metodo para mostrar ventanas de alerta
        public static void ShowAlertMessage(string error)
        {

            Page page = HttpContext.Current.Handler as Page;
            if (page != null)
            {
                error = error.Replace("'", "\'");
                ScriptManager.RegisterStartupScript(page, page.GetType(), "err_msg", "alert('" + error + "');window.location='../G6Pensum/ListarPensum.aspx';", true);
            }
        }

    }
}
